﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Configuration.Provider;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using TimeTracker.Provider;
using Utility;
using Utility.Configuration.Provider;

namespace TimeTracker
{
    public partial class Settings : Form
    {
        private ProviderManager<System.Configuration.Provider.ProviderBase> providerManager = null;
        protected ProviderManager<System.Configuration.Provider.ProviderBase> ProviderManager
        {
            get
            {
                if (this.providerManager == null)
                {
                    this.providerManager = new ProviderManager<System.Configuration.Provider.ProviderBase>("logProviders");
                }

                return this.providerManager;
            }
        }
        private ProviderManager<System.Configuration.Provider.ProviderBase> skinProviderManager = null;
        protected ProviderManager<System.Configuration.Provider.ProviderBase> SkinProviderManager
        {
            get
            {
                if (this.skinProviderManager == null)
                {
                    this.skinProviderManager = new ProviderManager<System.Configuration.Provider.ProviderBase>("skinProviders");
                }

                return this.skinProviderManager;
            }
        }

        private static int IdleTimeoutMultiplier = 30;

        public Settings()
        {
            InitializeComponent();

            this.trackBar1.Value = Convert.ToInt32(Properties.Settings.Default.IdleTimeout) / IdleTimeoutMultiplier;
            this.trackBar1_Scroll(null, null);

            this.comboBox1.Items.Clear();
            foreach (ProviderBase provider in this.ProviderManager.Providers)
            {
                this.comboBox1.Items.Add(provider);
            }
            this.comboBox1.DisplayMember = "Description";
            this.comboBox1.SelectedItem = this.ProviderManager.Providers[Properties.Settings.Default.Provider];

            this.comboBox4.Items.Clear();
            foreach (ProviderBase provider in this.SkinProviderManager.Providers)
            {
                this.comboBox4.Items.Add(provider);
            } 
            this.comboBox4.DisplayMember = "Description";
            this.comboBox4.SelectedItem = this.SkinProviderManager.Providers[Properties.Settings.Default.SkinProvider];

            this.comboBox2.SelectedItem = Properties.Settings.Default.GroupBy;
            this.comboBox3.SelectedItem = Properties.Settings.Default.OrderBy;
        }

        private void button1_Click(object sender, EventArgs e)
        {
            ProviderBase newProviderBase = (ProviderBase)this.comboBox1.SelectedItem;
            IProvider newProvider = (IProvider)newProviderBase;

            if (newProviderBase.Name != this.ProviderManager.Providers[Properties.Settings.Default.Provider].Name)
            {
                DialogResult result = MessageBox.Show("Would you like to attempt to convert your current data to the new provider?  This will overwrite any data in the new provider.", String.Empty, MessageBoxButtons.YesNo, MessageBoxIcon.Question);

                if (result == System.Windows.Forms.DialogResult.Yes)
                {
                    int projects = Manager.Instance.Projects.Count();

                    Progress progressForm = new Progress();
                    progressForm.Text = "Migrating data to new provider";
                    progressForm.ProgressBar.Minimum = 0;
                    progressForm.ProgressBar.Maximum = 100;
                    progressForm.ProgressBar.Step = 1;
                    progressForm.Show(this);

                    BackgroundWorker worker = new BackgroundWorker();
                    worker.WorkerReportsProgress = true;
                    worker.DoWork += new DoWorkEventHandler(delegate(object sender2, DoWorkEventArgs e2)
                    {
                        worker.ReportProgress(0, "Removing existing projects...");

                        newProvider.RemoveAllProjects();

                        int count = 0;

                        foreach (IProject project in Manager.Instance.Projects)
                        {
                            this.ConvertProject(newProvider, null, project);

                            string status = String.Format("Converting project '{0}'...", project.Name);

                            worker.ReportProgress(++count * 100 / projects, status);
                        }

                        worker.ReportProgress(99, "Saving...");
                        newProvider.Save();

                        worker.ReportProgress(100, "Complete!");
                    });

                    worker.ProgressChanged += new ProgressChangedEventHandler(delegate(object sender2, ProgressChangedEventArgs e2)
                    {
                        progressForm.ProgressBar.Value = e2.ProgressPercentage;
                        progressForm.Status = (string)e2.UserState;
                    });

                    worker.RunWorkerCompleted += new RunWorkerCompletedEventHandler(delegate(object sender2, RunWorkerCompletedEventArgs e2)
                    {
                        progressForm.Close();
                    });

                    worker.RunWorkerAsync();

                    while (worker.IsBusy)
                    {
                        System.Threading.Thread.Sleep(50);
                        Application.DoEvents();
                    }
                }
            }

            Properties.Settings.Default.Provider = newProviderBase.Name;

            ProviderBase newSkinProviderBase = (ProviderBase)this.comboBox4.SelectedItem;

            Properties.Settings.Default.SkinProvider = newSkinProviderBase.Name;

            Properties.Settings.Default.IdleTimeout = this.trackBar1.Value * IdleTimeoutMultiplier;

            Properties.Settings.Default.OrderBy = (string)this.comboBox3.SelectedItem;
            Properties.Settings.Default.GroupBy = (string)this.comboBox2.SelectedItem;

            Properties.Settings.Default.Save();

            this.Close();
        }

        private void ConvertProject(IProvider newProvider, IProject parent, IProject project)
        {
            IProject newProject = newProvider.CreateProject(parent, project.Name);

            foreach (IProject child in project.Projects)
            {
                this.ConvertProject(newProvider, newProject, child);
            }

            foreach (ISession session in project.Sessions)
            {
                ISession newSession = newProvider.CreateSession(newProject, session.StartTime, session.EndTime);
                newSession.Archived = session.Archived;

                foreach (INote note in session.Notes)
                {
                    newProvider.CreateNote(newSession, note.Time, note.Text);
                }
            }
        }
        
        private void trackBar1_Scroll(object sender, EventArgs e)
        {
            int seconds = this.trackBar1.Value * IdleTimeoutMultiplier;
            TimeSpan timeout = new TimeSpan(0, 0, seconds);

            if (seconds > 0)
            {
                this.label1.Text = String.Format("Idle timeout: {0}:{1:D2}", timeout.Minutes, timeout.Seconds);
            }
            else
            {
                this.label1.Text = "Idle timeout: never!";
            }
        }
    }
}
